import 'package:drift/drift.dart';
import 'package:drift_sqflite/drift_sqflite.dart';
import 'package:path_provider/path_provider.dart';
import 'tables.dart';

part 'database.g.dart';

@DriftDatabase(tables: [Users, Tasks])
class AppDatabase extends _$AppDatabase {
  AppDatabase() : super(_openConnection());

  @override
  int get schemaVersion => 1;

  // 用户相关操作
  Future<List<User>> getAllUsers() => select(users).get();

  Future<User?> getUserById(int id) =>
      (select(users)..where((u) => u.id.equals(id))).getSingleOrNull();

  Future<int> insertUser(UsersCompanion user) => into(users).insert(user);

  Future<bool> updateUser(UsersCompanion user) => update(users).replace(user);

  Future<int> deleteUser(int id) =>
      (delete(users)..where((u) => u.id.equals(id))).go();

  // 任务相关操作
  Future<List<Task>> getAllTasks() => select(tasks).get();

  Future<List<Task>> getTasksByUserId(int userId) =>
      (select(tasks)..where((t) => t.userId.equals(userId))).get();

  Future<Task?> getTaskById(int id) =>
      (select(tasks)..where((t) => t.id.equals(id))).getSingleOrNull();

  Future<int> insertTask(TasksCompanion task) => into(tasks).insert(task);

  Future<bool> updateTask(TasksCompanion task) => update(tasks).replace(task);

  Future<int> deleteTask(int id) =>
      (delete(tasks)..where((t) => t.id.equals(id))).go();

  Future<int> deleteTasksByUserId(int userId) =>
      (delete(tasks)..where((t) => t.userId.equals(userId))).go();

  // 联合查询：获取用户及其任务
  Future<List<UserWithTasks>> getUsersWithTasks() {
    return (select(users)..orderBy([(u) => OrderingTerm.asc(u.name)]))
        .get()
        .then((userList) {
      return Future.wait(
        userList.map((user) async {
          final userTasks = await getTasksByUserId(user.id);
          return UserWithTasks(user: user, tasks: userTasks);
        }),
      );
    });
  }

  // ========== 事务测试方法 ==========

  // 测试用例1: 批量添加用户和任务（成功事务）
  Future<String> testBatchInsertTransaction() async {
    return transaction(() async {
      try {
        // 批量添加用户
        final user1 = await into(users).insert(
          UsersCompanion(
            name: Value('事务测试用户1'),
            email: Value('transaction1@test.com'),
          ),
        );

        final user2 = await into(users).insert(
          UsersCompanion(
            name: Value('事务测试用户2'),
            email: Value('transaction2@test.com'),
          ),
        );

        // 为每个用户批量添加任务
        await into(tasks).insert(
          TasksCompanion(
            title: Value('用户1的任务1'),
            description: Value('这是事务测试中的任务'),
            userId: Value(user1),
          ),
        );

        await into(tasks).insert(
          TasksCompanion(
            title: Value('用户1的任务2'),
            description: Value('这是事务测试中的任务'),
            userId: Value(user1),
          ),
        );

        await into(tasks).insert(
          TasksCompanion(
            title: Value('用户2的任务1'),
            description: Value('这是事务测试中的任务'),
            userId: Value(user2),
          ),
        );

        return '批量插入事务执行成功：添加了2个用户和3个任务';
      } catch (e) {
        return '批量插入事务执行失败：$e';
      }
    });
  }

  // 测试用例2: 模拟转账操作（成功事务）
  Future<String> testTransferTransaction() async {
    return transaction(() async {
      try {
        // 获取现有用户
        final existingUsers = await getAllUsers();
        if (existingUsers.length < 2) {
          return '需要至少2个用户才能进行转账测试';
        }

        final user1 = existingUsers[0];
        final user2 = existingUsers[1];

        // 模拟转账：更新用户信息
        await update(users).replace(
          UsersCompanion(
            id: Value(user1.id),
            name: Value('${user1.name} (已转账)'),
            email: Value(user1.email),
          ),
        );

        await update(users).replace(
          UsersCompanion(
            id: Value(user2.id),
            name: Value('${user2.name} (已收款)'),
            email: Value(user2.email),
          ),
        );

        // 为两个用户都添加转账记录任务
        await into(tasks).insert(
          TasksCompanion(
            title: Value('转账操作记录'),
            description: Value('从${user1.name}转账给${user2.name}'),
            userId: Value(user1.id),
          ),
        );

        await into(tasks).insert(
          TasksCompanion(
            title: Value('收款操作记录'),
            description: Value('从${user1.name}收到转账'),
            userId: Value(user2.id),
          ),
        );

        return '转账事务执行成功：更新了2个用户信息，添加了2个转账记录任务';
      } catch (e) {
        return '转账事务执行失败：$e';
      }
    });
  }

  // 测试用例3: 错误回滚事务
  Future<String> testRollbackTransaction() async {
    return transaction(() async {
      try {
        // 第一步：正常插入用户
        final userId = await into(users).insert(
          UsersCompanion(
            name: Value('回滚测试用户'),
            email: Value('rollback@test.com'),
          ),
        );

        // 第二步：正常插入任务
        await into(tasks).insert(
          TasksCompanion(
            title: Value('回滚测试任务'),
            description: Value('这个任务应该被回滚'),
            userId: Value(userId),
          ),
        );

        // 第三步：故意制造错误（插入无效数据）
        await into(users).insert(
          UsersCompanion(
            name: Value(''), // 空名称，违反约束
            email: Value('invalid@test.com'),
          ),
        );

        // 如果执行到这里，说明没有回滚
        return '错误：事务应该回滚但没有回滚';
      } catch (e) {
        // 预期的错误，事务应该回滚
        return '事务回滚测试成功：$e\n所有操作已回滚';
      }
    });
  }

  // 测试用例4: 嵌套事务测试
  Future<String> testNestedTransaction() async {
    return transaction(() async {
      try {
        // 外层事务：添加用户
        final userId = await into(users).insert(
          UsersCompanion(
            name: Value('嵌套事务用户'),
            email: Value('nested@test.com'),
          ),
        );

        // 内层事务：添加任务
        await transaction(() async {
          await into(tasks).insert(
            TasksCompanion(
              title: Value('嵌套事务任务1'),
              description: Value('内层事务添加的任务'),
              userId: Value(userId),
            ),
          );

          await into(tasks).insert(
            TasksCompanion(
              title: Value('嵌套事务任务2'),
              description: Value('内层事务添加的任务'),
              userId: Value(userId),
            ),
          );
        });

        // 外层事务继续：再添加一个任务
        await into(tasks).insert(
          TasksCompanion(
            title: Value('嵌套事务任务3'),
            description: Value('外层事务添加的任务'),
            userId: Value(userId),
          ),
        );

        return '嵌套事务测试成功：添加了1个用户和3个任务';
      } catch (e) {
        return '嵌套事务测试失败：$e';
      }
    });
  }

  // 测试用例5: 条件事务（根据条件决定是否提交）
  Future<String> testConditionalTransaction(bool shouldCommit) async {
    return transaction(() async {
      try {
        final userId = await into(users).insert(
          UsersCompanion(
            name: Value('条件事务用户'),
            email: Value('conditional@test.com'),
          ),
        );

        await into(tasks).insert(
          TasksCompanion(
            title: Value('条件事务任务'),
            description: Value('这个任务根据条件决定是否保存'),
            userId: Value(userId),
          ),
        );

        if (!shouldCommit) {
          // 故意抛出异常来触发回滚
          throw Exception('条件不满足，触发回滚');
        }

        return '条件事务执行成功：shouldCommit=$shouldCommit';
      } catch (e) {
        return '条件事务执行结果：shouldCommit=$shouldCommit, 错误=$e';
      }
    });
  }

  // 测试用例6: 并发事务测试
  Future<String> testConcurrentTransactions() async {
    final results = await Future.wait([
      transaction(() async {
        await into(users).insert(
          UsersCompanion(
            name: Value('并发用户1'),
            email: Value('concurrent1@test.com'),
          ),
        );
        return '事务1完成';
      }),
      transaction(() async {
        await into(users).insert(
          UsersCompanion(
            name: Value('并发用户2'),
            email: Value('concurrent2@test.com'),
          ),
        );
        return '事务2完成';
      }),
      transaction(() async {
        await into(users).insert(
          UsersCompanion(
            name: Value('并发用户3'),
            email: Value('concurrent3@test.com'),
          ),
        );
        return '事务3完成';
      }),
    ]);

    return '并发事务测试结果：${results.join(', ')}';
  }

  // 测试用例7: 数据一致性检查
  Future<String> testDataConsistency() async {
    return transaction(() async {
      try {
        // 记录操作前的数据状态
        final initialUsers = await getAllUsers();
        final initialTasks = await getAllTasks();

        // 执行一系列操作
        final userId = await into(users).insert(
          UsersCompanion(
            name: Value('一致性测试用户'),
            email: Value('consistency@test.com'),
          ),
        );

        await into(tasks).insert(
          TasksCompanion(
            title: Value('一致性测试任务1'),
            userId: Value(userId),
          ),
        );

        await into(tasks).insert(
          TasksCompanion(
            title: Value('一致性测试任务2'),
            userId: Value(userId),
          ),
        );

        // 检查操作后的数据状态
        final finalUsers = await getAllUsers();
        final finalTasks = await getAllTasks();

        final userDiff = finalUsers.length - initialUsers.length;
        final taskDiff = finalTasks.length - initialTasks.length;

        return '数据一致性检查：用户增加了$userDiff个，任务增加了$taskDiff个';
      } catch (e) {
        return '数据一致性检查失败：$e';
      }
    });
  }
}

// 用户和任务的联合数据类
class UserWithTasks {
  final User user;
  final List<Task> tasks;

  UserWithTasks({required this.user, required this.tasks});
}

LazyDatabase _openConnection() {
  return LazyDatabase(() async {
    // 获取应用文档目录，但只需传文件名给drift_sqflite
    await getApplicationDocumentsDirectory(); // 仅保证依赖已初始化
    return SqfliteQueryExecutor.inDatabaseFolder(
      path: 'app_database.sqlite',
      logStatements: true,
      singleInstance: true,
    );
  });
}
